{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "accordion", "type": "registry:component", "dependencies": [], "devDependencies": [], "registryDependencies": [], "files": [ { "path": "./components/ui/accordion.tsx", "content": "'use client';\r\nimport React, { ReactNode, ReactElement, isValidElement } from 'react';\r\nimport { AnimatePresence, motion } from 'motion/react';\r\nimport { ChevronDown } from 'lucide-react';\r\nimport { cn } from '@/lib/utils';\r\n\r\ntype AccordionContextType = {\r\n isActive: boolean;\r\n value: string;\r\n onChangeIndex: (value: string) => void;\r\n};\r\n\r\nconst AccordionContext = React.createContext({\r\n isActive: false,\r\n value: '',\r\n onChangeIndex: () => {},\r\n});\r\n\r\nconst useAccordion = () => React.useContext(AccordionContext);\r\n\r\nexport function AccordionContainer({\r\n children,\r\n className,\r\n}: {\r\n children: ReactNode;\r\n className?: string;\r\n}) {\r\n return (\r\n
{children}
\r\n );\r\n}\r\n\r\nexport function AccordionWrapper({ children }: { children: ReactNode }) {\r\n return
{children}
;\r\n}\r\n\r\nexport function Accordion({\r\n children,\r\n multiple,\r\n defaultValue,\r\n}: {\r\n children: ReactNode;\r\n multiple?: boolean;\r\n defaultValue?: string | string[];\r\n}) {\r\n const [activeIndex, setActiveIndex] = React.useState(\r\n multiple\r\n ? defaultValue\r\n ? Array.isArray(defaultValue)\r\n ? defaultValue\r\n : [defaultValue]\r\n : []\r\n : defaultValue\r\n ? Array.isArray(defaultValue)\r\n ? [defaultValue[0]]\r\n : [defaultValue]\r\n : []\r\n );\r\n\r\n function onChangeIndex(value: string) {\r\n setActiveIndex((currentActiveIndex) => {\r\n if (!multiple) {\r\n return value === currentActiveIndex[0] ? [] : [value];\r\n }\r\n\r\n if (currentActiveIndex.includes(value)) {\r\n return currentActiveIndex.filter((i) => i !== value);\r\n }\r\n\r\n return [...currentActiveIndex, value];\r\n });\r\n }\r\n\r\n return React.Children.map(children, (child) => {\r\n if (!isValidElement<{ value?: string }>(child)) return null;\r\n\r\n const value = child.props.value ?? '';\r\n const isActive = multiple\r\n ? activeIndex.includes(value)\r\n : activeIndex[0] === value;\r\n\r\n return (\r\n \r\n {React.cloneElement(child)}\r\n \r\n );\r\n });\r\n}\r\n\r\nexport function AccordionItem({\r\n children,\r\n value,\r\n className,\r\n}: {\r\n children: ReactNode;\r\n value: string;\r\n className?: string;\r\n}) {\r\n const { isActive } = useAccordion();\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n}\r\n\r\nexport function AccordionHeader({\r\n children,\r\n customIcon,\r\n className,\r\n}: {\r\n children: ReactNode;\r\n customIcon?: boolean;\r\n className?: string;\r\n}) {\r\n const { isActive, value, onChangeIndex } = useAccordion();\r\n\r\n return (\r\n onChangeIndex(value)}\r\n >\r\n {children}\r\n {!customIcon && (\r\n \r\n )}\r\n \r\n );\r\n}\r\n\r\nexport function AccordionPanel({\r\n children,\r\n className,\r\n}: {\r\n children: ReactNode;\r\n className?: string;\r\n}) {\r\n const { isActive } = useAccordion();\r\n\r\n return (\r\n \r\n {isActive && (\r\n \r\n \r\n {children}\r\n \r\n \r\n )}\r\n \r\n );\r\n}\r\n", "type": "registry:component" } ] }